﻿/***************************************************************************/
/// <summary>
///  <title>SLIC UserAdministrationController</title>
///  <description>UserAdministrationController for User Management actions</description>
///  <copyRight>Copyright (c) 2011</copyRight>
///  <company>IronOne Technologies (Pvt)Ltd</company>
///  <createdOn>2011-08-01</createdOn>
///  <author>Lushanthan Sivaneasharajah</author>
///  <modification>
///     <modifiedBy></modifiedBy>
///      <modifiedDate></modifiedDate>
///     <description></description>
///  </modification>
/// </summary>
/// 
/***************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Net.Mail;
using System.Net;

#region SLICReferences
using SLIC.Models.EntityModel;
using SLIC.Models.UserAdministration;
using SLIC.Models.Enums;
#endregion SLICReferences

#region ThirdPartyReferences
using MvcContrib.Pagination;
using log4net;
using SLIC.Models.Job;
using System.Threading;
#endregion ThirdPartyReferences

namespace SLIC.Controllers
{
    public class UserAdministrationController : BaseController
    {
        protected static readonly ILog log = LogManager.GetLogger("root");
        // GET: /UserAdministration/
        #region ActionMethods

        public ActionResult Index()
        {
            //return View();
            return RedirectToAction("ViewUsers");
        }

        public ActionResult ViewUsers(int? page, string roleName = "Technical Officer")
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewUsers," + User.Identity.Name + ",[Params=(Role name:" + roleName + ",page:" + page + ")]");
            bool isAgent = false;

            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    roleName = roleName.Trim();
                    //string[] roles = Roles.GetAllRoles();

                    //if (!roles.Contains(roleName))
                    //    roleName = "Technical Officer";

                    ViewData["roleName"] = roleName;
                    if (roleName.ToLower().Equals("technical officer"))
                        isAgent = true;
                    ViewData["isAgent"] = isAgent;

                    string[] usernames = Roles.GetUsersInRole(roleName);

                    if (usernames.Count() == 0)
                        throw new GenException(678, "No Users found with the '" + roleName + "' role.");

                    List<UserDataModel> userList = (from u in context.Users
                                                    //where (isAgent ? (u.CSR_Code != null || u.CSR_Code != "") : (u.CSR_Code == null || u.CSR_Code == ""))
                                                    where usernames.Contains(u.aspnet_Users.UserName) && u.aspnet_Users.aspnet_Membership.IsApproved == true
                                                    select new UserDataModel
                                                     {
                                                         UserId = u.UserId,
                                                         firstName = u.FirstName,
                                                         lastname = u.LastName,
                                                         username = u.aspnet_Users.UserName,
                                                         CSRCode = u.CSR_Code,
                                                         isAgent = isAgent,
                                                         email = u.aspnet_Users.aspnet_Membership.Email
                                                     }).ToList();

                    //log for success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewUsers," + User.Identity.Name + ",[Params=(Role name:" + roleName + ",page:" + page + ")]");
                    return GetFormatView("UserAdministration/ViewUsers.aspx", userList.AsQueryable().AsPagination(page ?? 1, Convert.ToInt32(ConfigurationManager.AppSettings["pageSize"])));
                }
            }
            catch (GenException ex)
            {
                //log for exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewUsers," + User.Identity.Name + "," + ex.Message + ",[Params=(Role name:" + roleName + ",page:" + page + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for exception          
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewUsers," + User.Identity.Name + "," + ex.Message + ",[Params=(Role name:" + roleName + ",page:" + page + ")]");
                ModelState.AddModelError("err", new GenException(699, "Could not retrieve List of registered Users."));
                //  return RedirectToAction("ErrorView", "Base");
            }
            return GetFormatView("UserAdministration/ViewUsers.aspx", null);
        }

        public ActionResult ViewLockedUsers(int? page)
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewLockedUsers," + User.Identity.Name + ",[Params=(page:" + page + ")]");
            //bool isAgent = false;

            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    ViewData["roleName"] = "Locked User";
                    ViewData["isLockedUserPage"] = true;
                    IEnumerable<User> query = from u in context.Users
                                              where u.aspnet_Users.aspnet_Membership.IsLockedOut == true
                                              select u;
                    List<UserDataModel> userList = (from u in query
                                                    select new UserDataModel
                                                    {
                                                        firstName = u.FirstName,
                                                        UserId = u.UserId,
                                                        lastname = u.LastName,
                                                        username = u.aspnet_Users.UserName,
                                                        CSRCode = u.CSR_Code,
                                                        // isAgent = u.aspnet_Users.aspnet_Roles.ToList().Where(x=>x.RoleName=="")
                                                        isAgent = Roles.GetRolesForUser(u.aspnet_Users.UserName).Contains("Technical Officer"),
                                                        email = u.aspnet_Users.aspnet_Membership.Email
                                                    }).ToList();

                    if (userList == null || userList.Count == 0)
                        throw new GenException(708, "No users found.");

                    //log for success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewLockedUsers," + User.Identity.Name);
                    return GetFormatView("UserAdministration/ViewUsers.aspx", userList.AsQueryable().AsPagination(page ?? 1, Convert.ToInt32(ConfigurationManager.AppSettings["pageSize"])));
                }
            }
            catch (GenException ex)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewLockedUsers," + User.Identity.Name + "," + ex.Message + ",[Params=(page:" + page + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",ViewLockedUsers," + User.Identity.Name + "," + ex.Message + ",[Params=(page:" + page + ")]");
                ModelState.AddModelError("err", new GenException(699, "Could not retrieve List of registered Users."));
                return RedirectToAction("ErrorView", "Base");
            }
            return GetFormatView("UserAdministration/ViewUsers.aspx", null);
        }

        public ActionResult ViewUser(int? userId, string mode, string roleName)
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",View User," + User.Identity.Name + ",[Params=(User Id:" + userId + ",mode:" + mode + ",Role Name:" + roleName + ")]");
            UserDataModel user = null;

            try
            {
                ViewData["mode"] = mode;
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    List<aspnet_Roles> aspRoles = (from r in context.aspnet_Roles where r.RoleName != "emptyRole" select r).ToList();
                    ViewData["Roles"] = new SelectList(aspRoles, "RoleName", "RoleName");
                }

                //if (userId == null || userId == 0)
                if (String.IsNullOrWhiteSpace(mode) || mode == "n")
                {
                    //for new user
                    if (String.IsNullOrWhiteSpace(roleName))
                        throw new GenException(698, "User cannot be initiated without a role.");

                    user = new UserDataModel();
                    user.roleName = roleName;
                    user.isAgent = (roleName.Equals("Technical Officer")) ? true : false;
                    goto Finish;
                }

                //for delete and edit
                // user = this.GetUserWithPassword((int)userId, mode);
                if (userId == null)
                    throw new GenException(698, "Select User to edit or delete.");

                user = this.GetUser((int)userId);

                if (user.isLocked)
                {
                    ViewData["isLocked"] = true;
                    throw new GenException(802, "User is locked out. Please unlock the user first.");
                }

                //log for success
                log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",View User," + User.Identity.Name + ",[Params=(User Id:" + userId + ",mode:" + mode + ",Role Name:" + roleName + ")]");
            }
            catch (GenException ex)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",View User," + User.Identity.Name + "," + ex.Message + ",[Params=(User Id:" + userId + ",mode:" + mode + ",Role Name:" + roleName + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",View User," + User.Identity.Name + "," + ex.Message + ",[Params=(User Id:" + userId + ",mode:" + mode + ",Role Name:" + roleName + ")]");
                ModelState.AddModelError("err", new GenException(698, ex.Message));
                return RedirectToAction("ErrorView", "Base");
            }

        Finish:
            //log for success
            ViewData["roleName"] = user.roleName;
            log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",View User," + User.Identity.Name + ",[Params=(User Id:" + userId + ",mode:" + mode + ",Role Name:" + roleName + ")]");
            return GetFormatView("UserAdministration/UserDetail.aspx", user);
        }

        public ActionResult DeactivateUser(string userName, string mode, string role)
        {
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Deactivate User," + User.Identity.Name + ",[Params=(User name:" + userName + "Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            // UserDataModel user = null;

            try
            {
                ViewData["mode"] = mode;
                if (String.IsNullOrWhiteSpace(userName) || String.IsNullOrWhiteSpace(mode) || mode != "d")
                    throw new GenException(802, "Error occured while deleting.");

                MembershipUser us = Membership.GetUser(userName);
                us.IsApproved = false;
                Membership.UpdateUser(us);

                //log for success
                log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Deactivate User," + User.Identity.Name + ",[Params=(User name:" + userName + "Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            }
            catch (GenException ex)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Deactivate User," + User.Identity.Name + "," + ex.Message + ",[Params=(User name:" + userName + "Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Deactivate User," + User.Identity.Name + "," + ex.Message + ",[Params=(User name:" + userName + "Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(698, ex.Message));
            }

            log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Deactivate User," + User.Identity.Name + ",[Params=(User name:" + userName + "Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

            return RedirectToAction("ViewUsers", new { roleName = role });
            // return GetFormatView("UserAdministration/ViewUsers.aspx");
        }

        [HttpPost]
        public ActionResult AddUser(UserDataModel userModel)
        {
            //log for entry
            log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
            ViewData["roleName"] = userModel.roleName;
            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    List<aspnet_Roles> aspRoles = (from r in context.aspnet_Roles select r).ToList();
                    ViewData["Roles"] = new SelectList(aspRoles, "RoleName", "RoleName");

                    if (ModelState.IsValid)
                    {
                        #region validations

                        if (userModel == null)
                        {
                            throw new GenException(697, "User model cannot be empty.");
                        }

                        if (string.IsNullOrWhiteSpace(userModel.firstName) && string.IsNullOrWhiteSpace(userModel.lastname))
                        {
                            throw new GenException(697, "First Name and Last Name cannot be empty.");
                        }

                        Regex regex = new Regex(@"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$");

                        if (string.IsNullOrWhiteSpace(userModel.email) || !regex.IsMatch(userModel.email))
                        {
                            throw new GenException(697, "Enter valid email address.");
                        }

                        if (string.IsNullOrWhiteSpace(userModel.roleName))
                        {
                            throw new GenException(697, "User cannot be added without a role.");
                        }
                        if (userModel.roleName.ToLower() == "technical officer" && (userModel.CSRCode == null || String.IsNullOrWhiteSpace(userModel.CSRCode)))
                        {
                            throw new GenException(101, "Please Enter CSR Code.");
                        }

                        #endregion validations

                        MembershipCreateStatus memStatus;
                        Membership.CreateUser(userModel.username, userModel.password, userModel.email, "company name", "slic", true, out memStatus);

                        if (memStatus == MembershipCreateStatus.Success)
                        {
                            var userID = from u in context.aspnet_Users
                                         where u.UserName == userModel.username
                                         select u.UserId;

                            Roles.AddUserToRole(userModel.username, userModel.roleName);

                            User user = new User();
                            user.FirstName = userModel.firstName;
                            user.LastName = userModel.lastname;
                            user.UserGUID = userID.FirstOrDefault();

                            //  if (userModel.isAgent)
                            if (userModel.roleName.ToLower() == "technical officer" && !String.IsNullOrWhiteSpace(userModel.CSRCode))
                            {
                                user.CSR_Code = userModel.CSRCode.ToUpper();
                            }

                            //user.UserName = userModel.username;
                            //user.Email = userModel.email;
                            //user.UserStatus = 1;
                            //user.OfficePhone = userModel.officeno;
                            //user.mobileNumber = userModel.mobileno;

                            context.AddToUsers(user);
                            context.SaveChanges();

                            #region sendemail

                            //email should be sent to created user.
                            if (!string.IsNullOrWhiteSpace(userModel.email))
                            {
                                try
                                {
                                    MailMessage mail = new MailMessage();
                                    //set the addresses
                                    mail.From = new MailAddress(ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString());
                                    mail.To.Add(userModel.email);

                                    mail.Subject = "Welcome to the SLIC Motor Claims System!";
                                    mail.Body = "Dear " + userModel.firstName + ",\nWelcome to the SLIC Motor Claims System.  You may now log in  using the tablet.  Your login details are as follows;\n\n" + "UserName: " + userModel.username + " \nPassword: " + userModel.password + "\n\nPlease keep your login information confidential.\n\nThanking You,\nAdmin";
                                    //You may change the password after you log in. 

                                    //start sending email from a separate thread
                                    Email e = new Email(mail);
                                    Thread thread = new Thread(new ThreadStart(e.StartMailThread));
                                    thread.Start();
                                }
                                catch (Exception ex)
                                {
                                    log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name + "," + ex.Message + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                                    ModelState.AddModelError("err", new GenException(697, "Error occured while sending email"));
                                }
                            }
                            #endregion sendemail

                            //log for Success
                            log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                            return RedirectToAction("ViewUsers", new { roleName = userModel.roleName });
                        }
                        else if (memStatus == MembershipCreateStatus.DuplicateUserName)
                        {
                            //log for error
                            //  log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",AddUser," + User.Identity.Name + ",error:" + memStatus.ToString() + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ")]");
                            throw new GenException(697, "User Name exists. Choose a unique user name");
                        }
                        else if (memStatus == MembershipCreateStatus.InvalidUserName)
                        {
                            // log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",AddUser," + User.Identity.Name + ",error:" + memStatus.ToString() + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ")]");
                            throw new GenException(697, "Invalid Username. Select a proper Username.");
                        }
                        else
                        {
                            //log for error
                            //  log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",AddUser," + User.Identity.Name + ",error:" + memStatus.ToString() + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ")]");
                            throw new GenException(697, memStatus.ToString());
                        }
                    }
                    else
                    {
                        //log for error
                        log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name);
                    }
                }
            }
            catch (GenException ex)
            {
                //log for error
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name + "," + ex.Message + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //Delete User if not created on user table.

                //log for error
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Add User," + User.Identity.Name + "," + ex.Message + ",[Params=(User Name:" + userModel.username + ",Role Name:" + userModel.roleName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(697, "Could not add the user to the system"));
            }
            return GetFormatView("UserAdministration/UserDetail.aspx", userModel);
        }

        [HttpPost]
        public ActionResult UpdateUser(string existingRole, UserDataModel userModel)
        {
            try
            {
                log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Update User," + User.Identity.Name + ",[Params=(User Name:" + userModel.username + ",Role Name:" + existingRole + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    List<aspnet_Roles> aspRoles = (from r in context.aspnet_Roles select r).ToList();
                    ViewData["Roles"] = new SelectList(aspRoles, "RoleName", "RoleName");

                    //  if (ModelState.IsValid) // It asks for a strong password on update
                    //{
                    #region validations

                    if (userModel == null)
                    {
                        throw new GenException(697, "User model cannot be empty.");
                    }

                    if (string.IsNullOrWhiteSpace(userModel.firstName) && string.IsNullOrWhiteSpace(userModel.lastname))
                    {
                        throw new GenException(697, "First Name and Last Name cannot be empty.");
                    }

                    if (string.IsNullOrWhiteSpace(existingRole))
                    {
                        throw new GenException(697, "Existing Role of the user cannot be null.");
                    }

                    if (string.IsNullOrWhiteSpace(userModel.roleName))
                    {
                        throw new GenException(697, "User cannot be added without a role.");
                    }
                    Regex regex = new Regex(@"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$");

                    if (string.IsNullOrWhiteSpace(userModel.email) || !regex.IsMatch(userModel.email))
                    {
                        throw new GenException(697, "Enter valid email address.");
                    }

                    if (userModel.roleName.ToLower() == "technical officer" && (userModel.CSRCode == null || String.IsNullOrWhiteSpace(userModel.CSRCode)))
                    {
                        userModel.isAgent = true;
                        throw new GenException(101, "Please Enter CSR Code.");
                    }
                    #endregion validations

                    MembershipUser membershipuser = Membership.GetUser(userModel.username, false);

                    if (membershipuser.IsLockedOut)
                    {
                        throw new GenException(697, "The User is locked out! You can not update any information of the user. Unlock user first.");
                    }

                    membershipuser.Email = userModel.email;

                    /* if (userModel.password != userModel.OldPassword)
                     {
                         bool status = membershipuser.ChangePassword(userModel.OldPassword, userModel.password);
                         if (!status)
                         {
                             throw new GenException(697, "Error occured while changing the password. Please try again later.");
                         }
                     }
                     */
                    Membership.UpdateUser(membershipuser);

                    if (!(existingRole.Equals(userModel.roleName)))
                    {
                        //if (userModel.roleName == "Technical Officer" && userModel.CSRCode == null)
                        //{
                        //    userModel.isAgent = true;
                        //    throw new GenException(101, "Please Enter CSR Code.");
                        //}
                        Roles.RemoveUserFromRole(userModel.username, existingRole);
                        Roles.AddUserToRole(userModel.username, userModel.roleName);
                    }
                    //context.SaveChanges();

                    User user = (from u in context.Users
                                 where u.UserId == userModel.UserId
                                 select u).FirstOrDefault();

                    user.FirstName = userModel.firstName;
                    user.LastName = userModel.lastname;

                    //if (userModel.isAgent)
                    if (Roles.IsUserInRole(userModel.username, "Technical Officer"))
                    {
                        user.CSR_Code = userModel.CSRCode.ToUpper();
                    }
                    else
                    {
                        user.CSR_Code = null;
                    }
                    context.SaveChanges();

                    //log for Success
                    log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Update User," + User.Identity.Name + ",[Params=(User Name:" + userModel.username + ",Role Name:" + existingRole + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                    return RedirectToAction("ViewUsers", new { roleName = userModel.roleName });
                    //}
                    //else
                    //{
                    //    //log for error
                    //    log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",EditUser," + User.Identity.Name);
                    //}                   
                }

            }
            catch (GenException ex)
            {
                //log for error
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Update User," + User.Identity.Name + "," + ex.Message);
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for error
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Update User," + User.Identity.Name + "," + ex + ",[Params=(User Name:" + userModel.username + ",Role Name:" + existingRole + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(368, "Could not edit the user to the system.Please try again later."));
            }

            return GetFormatView("UserAdministration/UserDetail.aspx", userModel);
            //return ViewUser(userModel.UserId);
        }

        [HttpPost]
        public ActionResult UnlockUsers(IList<string> chkSelected, IEnumerable<UserDataModel> userList)
        {
            ViewData["roleName"] = "Locked User";
            ViewData["isLockedUserPage"] = true;
            //UserDataModel user = null;
            //List<int> userIdList =            

            try
            {
                log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + ",[Params=(Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

                if (chkSelected == null || chkSelected.Count == 0)
                    throw new GenException(789, "Function not applicable.");

                //chkSelected = chkSelected.Where(x => x.ToString().ToLower() != "true" || x.ToString().ToLower() != "false").ToList();
                chkSelected = chkSelected.Where(x => x.ToString().ToLower() != "false").ToList();

                //foreach (var item in chkSelected)
                //{
                //    if (item == "true" || item == "false")
                //    {

                //    }
                //}
                if (chkSelected.Count == 0)
                    throw new GenException(789, "Please select users to unlock.");

                foreach (string userName in chkSelected)
                {
                    try
                    {
                        MembershipUser usr = Membership.GetUser(userName);

                        if (usr == null)
                        {
                            throw new GenException(111, userName + " not found");
                        }

                        usr.UnlockUser();
                        log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");

                    }
                    catch (GenException e)
                    {
                        //Log Error
                        ModelState.AddModelError("err", e);
                        log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                    }
                    catch (Exception e)
                    {
                        //Log Error
                        ModelState.AddModelError("err", new GenException(112, e.Message));
                        log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                    }
                }

                //log for success
                log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + ",[Params=(Users:" + String.Join(",", chkSelected) + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                // RedirectToAction("ViewLockedUsers");
            }
            catch (GenException ex)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + "," + ex.Message + ",[Params=(Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", ex);
            }
            catch (Exception ex)
            {
                //log for exception
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Unlock Users," + User.Identity.Name + "," + ex.Message + ",[Params=(Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(698, ex.Message));
                return RedirectToAction("ErrorView", "Base");
            }
            return this.ViewLockedUsers(1);
            // return GetFormatView("UserAdministration/ViewUsers.aspx", userList);
        }
        #endregion ActionMethods

        public ActionResult ResetPassword(string userName, string role)
        {
            try
            {
                log.Info(LogPoint.Entry.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Reset Password," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Role Name:" + role + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                MembershipUser user = Membership.GetUser(userName);

                if (user.IsLockedOut)
                {
                    throw new GenException(908, "User account has been locked. Please unlock user first!");
                }
                string newPassword = user.ResetPassword();
                string email = user.Email;

                if (!string.IsNullOrWhiteSpace(email))
                {
                    try
                    {
                        MailMessage mail = new MailMessage();
                        //set the addresses
                        mail.From = new MailAddress(ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString());
                        mail.To.Add(email);

                        mail.Subject = "[SLIC Motor Claim System] Password has been reset";
                        mail.Body = "Dear User,\n" + "Your Password has been reset by the Administrator." + " \nYour new Password is " + newPassword;
                        var client = new SmtpClient(ConfigurationManager.AppSettings["SMTP_HOST"].ToString(), Convert.ToInt32(ConfigurationManager.AppSettings["SMTP_PORT"].ToString()))
                        {
                            Credentials = new NetworkCredential(ConfigurationManager.AppSettings["MAIL_SERVER_USERNAME"].ToString(), ConfigurationManager.AppSettings["MAIL_SERVER_PASSWORD"].ToString()),
                            EnableSsl = true
                        };
                        client.Send(mail);
                        mail.Dispose();
                        log.Info(LogPoint.Success.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Reset Password-Email," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Role Name:" + role + ",Email :" + email + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                    }
                    catch (Exception)
                    {
                        log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Reset Password-Email," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Role Name:" + role + ",Email :" + email + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                        ModelState.AddModelError("err", new GenException(201, "Error occured while sending email alerts after reseting the password."));
                        //  return null;
                    }
                }
            }
            catch (GenException e)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Reset Password," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Role Name:" + role + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", e);
            }
            catch (Exception e)
            {
                log.Error(LogPoint.Failure.ToString() + "," + this.ControllerContext.Controller.ToString() + ",Reset Password," + User.Identity.Name + ",[Params=(User Name:" + userName + ",Role Name:" + role + ",Client IP:" + Request.ServerVariables["REMOTE_ADDR"] + ")]");
                ModelState.AddModelError("err", new GenException(201, e.Message));
            }
            //RedirectToAction("ViewUsers", "UserAdministration", new { roleName = role, page = 1 });
            //Wrong look at the URL
            return this.ViewUsers(1, role);
        }

        #region NonActionMethods

        [NonAction]
        private UserDataModel GetUserWithPassword(int userId, string mode)
        {
            try
            {
                UserDataModel usermodel = this.GetUser(userId);

                if (mode == "e" && !usermodel.isLocked)
                {
                    MembershipUser memUser = Membership.GetUser(usermodel.username);
                    usermodel.password = memUser.GetPassword("slic");
                    usermodel.ConfirmPassword = usermodel.password;
                    usermodel.OldPassword = usermodel.password;

                    //throw new GenException(802, "User is locked out. Please unlock the user first.");
                }
                return usermodel;
            }
            catch (GenException)
            {
                throw;
            }
            catch (Exception)
            {
                throw;
            }
        }

        [NonAction]
        private UserDataModel GetUser(int userId)
        {
            //GetUserWithRoles
            try
            {
                using (SLICEntities context = DataObjectFactory.CreateContext())
                {
                    User user = (from u in context.Users where u.UserId == userId select u).FirstOrDefault();
                    if (user == null)
                    {
                        throw new GenException(801, "User not found in database.");
                    }

                    UserDataModel usermodel = new UserDataModel(user);

                    MembershipUser memUser = Membership.GetUser(user.UserGUID);
                    usermodel.username = memUser.UserName;
                    usermodel.isLocked = memUser.IsLockedOut;
                    usermodel.email = memUser.Email;
                    usermodel.roles = Roles.GetRolesForUser(memUser.UserName);
                    usermodel.roleName = usermodel.roles[0];
                    usermodel.isAgent = Roles.IsUserInRole(memUser.UserName, "Technical Officer");
                    return usermodel;
                }
            }
            catch (GenException)
            {
                throw;
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion NonActionMethods
    }
}
